
#ifndef MBCLIENT_H
#define MBCLIENT_H

#include <QObject>
#include <QTimer>
#include <QModbusDataUnit>
#include <QModbusDevice>
#include "datatype.h"

class QModbusTcpClient;
class QModbusReply;

class ModbusClient : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool connected READ isConnected NOTIFY connectedChanged)
    Q_PROPERTY(QString status READ status NOTIFY statusChanged)
    Q_PROPERTY(int deviceId READ deviceId NOTIFY deviceDataChanged)
    Q_PROPERTY(QString deviceName READ deviceName NOTIFY deviceDataChanged)
    Q_PROPERTY(float deviceValue READ deviceValue NOTIFY deviceDataChanged)
    Q_PROPERTY(bool deviceStatus READ deviceStatus NOTIFY deviceDataChanged)
    Q_PROPERTY(qint32 deviceTimestamp READ deviceTimestamp NOTIFY deviceDataChanged)
    Q_PROPERTY(float temperature READ temperature NOTIFY deviceDataChanged)
    Q_PROPERTY(float humidity READ humidity NOTIFY deviceDataChanged)
    Q_PROPERTY(int pressure READ pressure NOTIFY deviceDataChanged)
    Q_PROPERTY(int alarmStatus READ alarmStatus NOTIFY deviceDataChanged)
    Q_PROPERTY(QString description READ description NOTIFY deviceDataChanged)

public:
    explicit ModbusClient(QObject *parent = nullptr);
    ~ModbusClient();

    Q_INVOKABLE bool connectToServer(const QString& address, int port);
    Q_INVOKABLE void disconnectFromServer();
    Q_INVOKABLE void writeDeviceId(int id);
    Q_INVOKABLE void writeDeviceName(const QString& name);
    Q_INVOKABLE void writeDeviceValue(float value);
    Q_INVOKABLE void writeDeviceStatus(bool status);
    Q_INVOKABLE void writeTemperature(float temp);
    Q_INVOKABLE void writeHumidity(float humidity);
    Q_INVOKABLE void writePressure(int pressure);
    Q_INVOKABLE void writeAlarmStatus(int status);
    Q_INVOKABLE void writeDescription(const QString& description);
    Q_INVOKABLE void startReadTimer();
    Q_INVOKABLE void stopReadTimer();

    bool isConnected() const;
    QString status() const;

    // 数据访问方法
    int deviceId() const { return m_deviceData.id; }
    QString deviceName() const { return m_deviceData.name; }
    float deviceValue() const { return m_deviceData.value; }
    bool deviceStatus() const { return m_deviceData.status; }
    qint32 deviceTimestamp() const { return m_deviceData.timestamp; }
    float temperature() const { return m_deviceData.temperature; }
    float humidity() const { return m_deviceData.humidity; }
    int pressure() const { return m_deviceData.pressure; }
    int alarmStatus() const { return m_deviceData.alarmStatus; }
    QString description() const { return m_deviceData.description; }

signals:
    void connectedChanged();
    void statusChanged();
    void deviceDataChanged();
    void errorOccurred(const QString& error);
    void readCompleted();
    void writeCompleted();

private slots:
    void handleConnectionStateChanged();
    void handleDeviceError(QModbusDevice::Error error);
    void handleReadReady();
    void handleWriteReply(QModbusReply* reply);
    void onReadTimeout();
    void readAllData();

private:
    void setStatus(const QString& status);
    void processReadResult(const QModbusDataUnit& unit);
    void sendWriteRequest(QModbusDataUnit::RegisterType type, int address, const QVector<quint16>& values);

    QModbusTcpClient* modbusClient;
    QString m_status;
    DeviceData m_deviceData;
    QTimer* readTimer;
    QTimer* timeoutTimer;
    bool m_reading;
};

#endif // MBCLIENT_H
